﻿#define STORE
#define STOREPRINT
using System;
using System.Globalization;
using System.Text;
using System.IO;
using NetTao.Dao;
using NetTao.Model;

namespace NetTao.Spider
{
    public class NovelStore : SpiderBase
    {
        private readonly DaoArticle _daoArticle = new DaoArticle(Config.ConfigManage.Instace().GetConfig().ConnString);

        private readonly DaoChapter _daoChapter = new DaoChapter(Config.ConfigManage.Instace().GetConfig().ConnString);

        private readonly DaoAttachs _daoAttachs = new DaoAttachs(Config.ConfigManage.Instace().GetConfig().ConnString);

        private ArticleInfo _lastInfo = new ArticleInfo();
        
        private static NovelStore _novelStore;

        //private int HasVipChapter { get; set; }

        public static NovelStore Instace()
        {
            return _novelStore ?? (_novelStore = new NovelStore());
        }

        private NovelStore()
        {
            //HasVipChapter = 0;
            if (_daoArticle == null) return;
            Config.AppCache.Instace().MaxArticleID = _daoArticle.GetArticleMaxID();
            Config.AppCache.Instace().MaxChapterID = _daoChapter.GetChapterMaxID();
            Config.AppCache.Instace().MaxAttachID = _daoAttachs.GetAttachMaxID();
        }

        public void StoreNovel(ref Analyser.AnalyseArticle analyseArticle)
        {
            var article = _daoArticle.GetByName(analyseArticle.Article.articlename);
            var exists = !string.IsNullOrEmpty(article.articlename);
            if (!exists)
            {
                analyseArticle.Article.articleid = Config.AppCache.Instace().MaxArticleID;
                analyseArticle.Article.postdate = int.Parse(DateTime.Now.ToString("yyMMddHHmm"));
                analyseArticle.Article.lastupdate = int.Parse(DateTime.Now.ToString("yyMMddHHmm"));
                _daoArticle.Add(analyseArticle.Article);
                _lastInfo = analyseArticle.Article;
                StoreCover(analyseArticle.Article, analyseArticle.Encode,Config.ConfigManage.Instace().GetConfig().FilePath);
            }
            else
            {
                analyseArticle.Article = article;
                analyseArticle.Article.lastupdate = int.Parse(DateTime.Now.ToString("yyMMddHHmm"));
            }
        }

        private void StoreCover(ArticleInfo article, Encoding encode, string path)
        {
            if (string.IsNullOrEmpty(article.cover)) return;
            var cover = Utils.HttpHelper.GetImage(article.cover, encode);
            var link = article.cover;
            var coverPath = string.Format(@"{0}\files\article\image\{1}", path, article.articleid/1000);
            if (!Directory.Exists(coverPath))
                Directory.CreateDirectory(coverPath);

            coverPath += string.Format(@"\{0}{1}", article.articleid, link.Substring(link.Length - 4, 4));
            cover.Save(coverPath);
        }

        public bool StoreChapters(ref Analyser.AnalyseBookReader analyseBookReader,ref Analyser.AnalyseChapter analyseChapter)
        {

            var list = _daoChapter.GetList(analyseBookReader.Article.articleid);
            if (list.Count == analyseBookReader.BookReader.Count)
            {
                RepeatTimes++;
                return false;
            }
            string msg;
            var lastVolumeID = 0;
            var cindex = 0;
            foreach (var chapterInfo in analyseBookReader.BookReader)
            {
                chapterInfo.articleid = analyseBookReader.Article.articleid;
                if (cindex < list.Count) //old
                {
                    chapterInfo.isnew = chapterInfo.ctype == 1 ? 1 : 0;
                    chapterInfo.volumeid = list[cindex].volumeid; //old volume id
                    chapterInfo.chapterid = list[cindex].chapterid; //old chapter id
                }
                else if (cindex >= list.Count) //new
                {
                    chapterInfo.chapterid = Config.AppCache.Instace().MaxChapterID;
                    if (chapterInfo.chaptertype == 1) //volume
                    {
                        lastVolumeID = analyseBookReader.BookReader[cindex].chapterid;
                    }
                    else if (chapterInfo.chaptertype == 0 && lastVolumeID > 0)
                    {
                        chapterInfo.volumeid = lastVolumeID;
                    }
                    _daoChapter.Add(chapterInfo);
                }
                if (cindex == analyseBookReader.BookReader.Count - 1)
                {
                    analyseBookReader.Article.lastchapterid = chapterInfo.chapterid;
                    analyseBookReader.Article.lastchapter = chapterInfo.chaptername;
                }
                if (chapterInfo.chaptertype != 1 && chapterInfo.isnew != 0)
                {
                    if (chapterInfo.isvip == 0)
                    {
#if STORE
                        if(Config.ConfigManage.Instace().GetConfig().GatherType=="WEB")
                        {
                            GetChapter(ref analyseChapter, chapterInfo);   
                        }
#endif
                        #region set last info

                        _lastInfo.articleid = chapterInfo.articleid;
                        _lastInfo.lastchapterid= chapterInfo.chapterid;
                        _lastInfo.lastchapter= chapterInfo.chaptername;
                        _lastInfo.lastvolumeid= chapterInfo.volumeid;
                        _lastInfo.chapters++;

                        #endregion
                    }
                }
                cindex++;
#if STOREPRINT
                msg = string.Format("IN {0} {1} {2}", chapterInfo.articlename, chapterInfo.chapterid,chapterInfo.chaptername);
                Utils.LogManage.Instace().Info(true, msg);
#endif
            }
            return true;
        }

        public void StoreChaptersBySecond(Analyser.AnalyseBookReader sourceAnalyseBookReader,
            Analyser.AnalyseBookReader analyseBookReader,
            ref Analyser.AnalyseChapter analyseChapter)
        {
            var index = 0;
            foreach (ChapterInfo sourceInfo in sourceAnalyseBookReader.BookReader)
            {
                if (sourceInfo.chaptertype != 1 && sourceInfo.isnew != 0 && sourceInfo.isvip == 1)
                {
                    if (analyseBookReader.DicBookReader.ContainsKey(sourceInfo.chaptername))//?san需要名称之类的比较
                    {
                        GetChapter(ref analyseChapter,
                                   analyseBookReader.BookReader[analyseBookReader.DicBookReader[sourceInfo.chaptername]]);
                    }
                }
                index++;
            }
        }

        private void GetChapter(ref Analyser.AnalyseChapter analyseChapter, ChapterInfo chapter)
        {
            analyseChapter.SetContent(Utils.HttpHelper.Get(chapter.contentslink, analyseChapter.Encode));
            if (string.IsNullOrEmpty(analyseChapter.GetContent()))
            {
                Utils.LogManage.Instace().Error("[10002]Content is empty.");
                Utils.LogManage.Instace().Error(chapter.contentslink);
                return;
            }
            //analyseChapter.SetContent(Utils.HttpHelper.Get("http://www.qidian.com/BookReader/58957,41759098.aspx", analyseChapter.Encode));
            var jsTxtLink = "";
            var encoding = "";
            analyseChapter.AnalyseChapterInfo(chapter, ref jsTxtLink, ref encoding);
            if(!string.IsNullOrEmpty(jsTxtLink))
            {
                analyseChapter.ContentTxt = Utils.HttpHelper.Get(jsTxtLink, Encoding.GetEncoding(encoding));
                analyseChapter.ClearTxtMark();
            }
            if (analyseChapter.Attahcs==null|| analyseChapter.Attahcs.Count == 0)
            {
                SaveChapterTxt(chapter, analyseChapter.ContentTxt,
                                   Config.ConfigManage.Instace().GetConfig().FilePath);
                if (chapter.ctype == 1)
                {
                    chapter.ctype = 0;
                    _daoChapter.Update(chapter);
                    _daoAttachs.UpdateAttachInvalid(chapter.articleid);
                }
            }
            else
            {
                chapter.ctype = 1;
                _daoChapter.Update(chapter);
                foreach (var attach in analyseChapter.Attahcs)
                {
                    DownloadAttach(attach);
                    _daoAttachs.Add(attach);
                }
            }
        }

        private void SaveChapterTxt(ChapterInfo chapter, string txtContent, string filePath)
        {
            var txtPath = string.Format(@"{0}\files\article\txt\{1}\{2}", filePath, chapter.articleid/1000,
                                           chapter.articleid);
            if (!Directory.Exists(txtPath))
                Directory.CreateDirectory(txtPath);

            txtPath += @"\" + chapter.chapterid.ToString(CultureInfo.InvariantCulture) + ".txt";
            using (var sw = new StreamWriter(txtPath, false, Encoding.GetEncoding("utf-8")))
            {
                sw.Write(txtContent);
                sw.Close();
            }
        }

        private void DownloadAttach(AttachInfo attach)
        {
            var link = string.Format("{0}", attach.chapterid.ToString(CultureInfo.InvariantCulture));
        }

        public void CompleteStore()
        {
            _daoArticle.Update(_lastInfo);
        }
    }
}
